Closed Bug 1529884 Opened 6 years ago Closed 6 years ago

All public methods of editor which may be called JS API should have argument of caller type

Categories

(Core :: DOM: Editor, enhancement, P2)

65 Branch
enhancement

Tracking

()

RESOLVED FIXED
mozilla69
Tracking Status
firefox68 --- wontfix
firefox69 --- fixed

People

(Reporter: masayuki, Assigned: masayuki)

References

(Blocks 1 open bug)

Details

Attachments

(8 files, 1 obsolete file)

47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review

beforeinput event should not be fired if the edit action is caused by web apps, e.g., document.execCommand() (is there any other situation?).

So, public methods which may be called by nsHTMLDocument::ExecCommand() should have the caller type to distinguish whether we need to dispatch beforeinput or not.

Priority: -- → P2

I'm still struggling with this. Currently, we use this path:

  1. nsHTMLDocument::ExecCommand()
  2. nsCommandManager::DoCommand()
  3. nsIController::DoCommand() or nsICommandController::DoCommandWithParams()
  4. nsIControllerCommandTable::DoCommand() or nsIControllerCommandTable::DoCommandWithParams()
  5. nsControllerCommandTable::DoCommand() or nsControllerCommandTable::DoCommandParams()
  6. nsIControllerCommand::DoCommand() or nsIControllerCommand::DoCommandParams()

I've already some those interfaces builtin classes. However, nsIController, nsICommandController and nsIControllerCommand are implemented by JS in comm-central. If we use implicit_context for their methods, the latest context is passed. So, even if execCommand() is called by content script but one of them is implemented by JS, the context becomes chrome context. Note that this does not occur with current Firefox, and JS isn't enabled by default on Tb and some other Gecko embedded applications. Therefore, we can use this approach at least.

However, I'm looking for better approach. The simplest idea is, each edit command class check current context. This approach has same concern about passing context in all interfaces, but the implementation becomes simpler.

Currently, my better approach is, execCommand() access edit command class or editor directly. Then, we can improve the performance and it may make benchmark score better since benchmarks use execCommand() a lot, IIRC.

Hmm, unfortunately, the patches become too big and they are really difficult to review for anybody. So, I'll file separate bugs for editor part changes to make reviews easier. However, unfortunately, Makoto-san will be away for 10 days due to Japanese national holidays but I need to keep working to fix these bugs. So, perhaps, I'll request reviews even for editor part to smaug when he's away.

Currently, there are no tests of execCommand() without editable element.
Additionally, current Gecko propagate "cut" and "copy" commands into child
document (I think it's odd).

This test checks the behavior. The expected results are considered mainly
from Chrome, but also Chrome does not pass all tests because some their
behavior are odd. E.g., Chrome returns true for execCommand("styleWithCSS")
even though it does nothing. So, this patch makes its expected result false.

Currently, nsHTMLDocument converts HTML command (e.g., used by execCommand()
to internal XUL command with array in the global space. However, it requires
scan of the array for every command access.

This patch makes nsHTMLDocument use hashtable to make the conversion faster.

New mapping info comes from:

Note that CommandParamType will be removed by part 6 because ExecCommand() starts to treat EditorCommand directly from it.

This patch creates ConvertToInternalCommand() as the replacement of
ConvertToMidasInternalCommand() and ConvertToMidasInternalCommandInner().
It returns InternalCommandData. Therefore, every caller can compare
Command instead of using strcmp().

aAdjustedValue of nsHTMLDocument::ConvertToInternalCommand() is not
nullptr when it's called by ExecCommand() or QueryCommandState().
However, QueryCommandState() does not need the value actually. Therefore,
we can move the input value check from ExecCommand() toConvertToInsernalCommand()`.

Most commands are dispatched only when the document has contenteditable or
in designMode. In such case, command target is considered with the following
order:

  1. HTMLEditor for the document.
  2. TextEditor if focused element has one.
  3. Other command controller table associated with window or DocShell.

In the case of #1 and #2, ExecCommand() can use EditorCommand directly.

In case of #3, there are two situations. One is when command is the clipboard
write command, i.e., "paste", it's targeted to the window. The other is, when
command is a clipboard read command, i.e., "cur" or "copy", it's targeted to
its window or focused subdocument via DocShell.

But note that clipboard write commands are special cases. They have always been
handled with active element since they are always handled with DocShell.
Therefore, the priority between #1 and #2 is opposite only at handling them.

nsHTMLDocument::ExecCommand() knows subject principal. This patch makes
it tell EditorCommand::DoCommand() and EditorCommand::DoCommandParam().
Then, makes they tell each editor public methods which may cause dispatching
beforeinput event once we implement it. Finally, each editor public
method sets it to the constructor of EditorBase::AutoEditActionDataSetter.
This means that when editor tries to dispatch beforeinput event, editor
can check whether it's called by JS or not from everywhere once
EditorBase::AutoEditActionDataSetter starts to store it.

These are complicated patches, will take several days to review.

(In reply to Olli Pettay [:smaug] from comment #11)

These are complicated patches, will take several days to review.

Sure. No problem. And please give higher priority to the other patches which need to be landed into 68.

Attachment #9062151 - Attachment is obsolete: true
Attachment #9062146 - Attachment description: Bug 1529884 - part 1: Make nsHTMLDocument use hashtable to map HTML command and internal command data → Bug 1529884 - part 1: Make Document use hashtable to map HTML command and internal command data
Attachment #9062148 - Attachment description: Bug 1529884 - part 3: Make nsHTMLDocument::ConvertToInternalCommand() check the input value when the caller requires adjusted value → Bug 1529884 - part 3: Make Document::ConvertToInternalCommand() check the input value when the caller requires adjusted value
Attachment #9062149 - Attachment description: Bug 1529884 - part 4: Make nsHTMLDocument::ExecCommand() do security check first if given command is supported → Bug 1529884 - part 4: Make Document::ExecCommand() do security check first if given command is supported
Attachment #9062150 - Attachment description: Bug 1529884 - part 5: Make nsHTMLDocument::ExecCommand() use EditorCommand directly as far as possible → Bug 1529884 - part 5: Make Document::ExecCommand() use EditorCommand directly as far as possible
Attachment #9062153 - Attachment description: Bug 1529884 - part 7: Send subject principal at nsHTMLDocument::ExecCommand() to constructor of EditorBase::AutoEditActionDataSetter → Bug 1529884 - part 6: Through subject principal at Document::ExecCommand() to constructor of EditorBase::AutoEditActionDataSetter

(I'd like to clean up the related methods with direct access to EditorCommand in another bug.)

Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/66cd074a9182 part 0: Add new WPT to check whether `document.execCommand()` without editable element and with editable parent or child document r=smaug https://hg.mozilla.org/integration/autoland/rev/dd9794f7d400 part 1: Make Document use hashtable to map HTML command and internal command data r=smaug https://hg.mozilla.org/integration/autoland/rev/f44697e42459 part 2: Implement ConvertToMidasInternalCommand() as returning InternalCommandData r=smaug https://hg.mozilla.org/integration/autoland/rev/460df951943a part 3: Make Document::ConvertToInternalCommand() check the input value when the caller requires adjusted value r=smaug https://hg.mozilla.org/integration/autoland/rev/7af1b30df51c part 4: Make Document::ExecCommand() do security check first if given command is supported r=smaug https://hg.mozilla.org/integration/autoland/rev/258c4da663ca part 5: Make Document::ExecCommand() use EditorCommand directly as far as possible r=smaug https://hg.mozilla.org/integration/autoland/rev/9ee7acab98a4 part 6: Through subject principal at Document::ExecCommand() to constructor of EditorBase::AutoEditActionDataSetter r=smaug https://hg.mozilla.org/integration/autoland/rev/87b36ec23f8a part 7: Make `ExecCommand()` and related methods use `a` prefix for every parameter r=smaug
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/17251 for changes under testing/web-platform/tests
Upstream web-platform-tests status checks passed, PR will merge once commit reaches central.
Depends on: 1558412
No longer depends on: 1558412
Regressions: 1558412
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: